package com.vito.oa.act.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.vito.act.model.ActExApproveInfoModel;
import com.vito.base.authoriza.model.FileModel;
import com.vito.base.authoriza.model.UserModel;
import com.vito.base.authoriza.service.FileService;
import com.vito.base.authoriza.service.UserService;
import com.vito.base.model.FtpModel;
import com.vito.base.model.MyHashMap;
import com.vito.base.util.Contants;
import com.vito.base.util.FtpHelper;
import com.vito.base.util.StringUtil;
import com.vito.base.util.Validata;
import com.vito.oa.act.dao.OaActPrintMapper;
import com.vito.oa.act.extend.dao.OaActExDataFollowMapper;
import com.vito.oa.act.extend.model.OaActExApproveInfoModel;
import com.vito.oa.act.extend.service.OaActProgressTableService;
import com.vito.oa.act.print.ConvertHtml;
import com.vito.oa.act.print.ParseHtml;
import com.vito.oa.act.print.PrintInfo;
import com.vito.oa.act.print.PrintInfo.Approval;
import com.vito.oa.act.service.OaActPrintService;

@Service
public class OaActPrintServiceImpl implements OaActPrintService {
	private static final Logger log = LoggerFactory.getLogger(OaActPrintServiceImpl.class);
	@Autowired
	private OaActPrintMapper oaActPrintMapper;
	@Autowired
	private OaActProgressTableService actProgressTableService;
	@Autowired
	private FileService fileServiceImpl;
	@Autowired
	private OaActExDataFollowMapper actExDataFollowMapper;
	@Autowired
	private UserService userServiceImpl;
	
	@Override
	public synchronized FileModel printProcess(PrintInfo pInfo) {
		FileModel fileModel = new FileModel();
		try {
			ConvertHtml.createHtmlFromString(pInfo);
	
			File file = new File(ParseHtml.DEST);
			file.getParentFile().mkdirs(); 
			if (file.exists()) {
				file.delete();
			}		
			ParseHtml.createPdf(ParseHtml.DEST);
			String path = StringUtil.getDate("_yyyy_MM_dd_");
			
			fileModel.setFileId(fileServiceImpl.updCreateId());
			fileModel.setFilePath(path);
			fileModel.setFileName(pInfo.getFileName());
			fileModel.setFileMd5("OA_PRINT");
			fileModel.setFileExt("pdf");
			
			new FtpHelper().upload(file, fileModel.getFileId()+"."+fileModel.getFileExt(), path.replaceAll("_", "/"));
			fileServiceImpl.save(fileModel);
		} catch (Exception e) {
			log.error("保存pdf文件失败",e);
			e.printStackTrace();
			return null;
		}
		return fileModel;
	}

	@Override
	public List<OaActExApproveInfoModel> queryProcessInfo(OaActExApproveInfoModel actExApproveInfoModel) {		
		return oaActPrintMapper.queryProcessInfo(actExApproveInfoModel);	
			
	}	
	@Override
	public OaActExApproveInfoModel queryProcessInfo(String businessId) {		
		return oaActPrintMapper.queryProcessInfoByBusId(businessId);	
			
	}	

	@Override
	public PrintInfo getInfoPdf(ActExApproveInfoModel approve){
		List<ActExApproveInfoModel> list = new ArrayList<ActExApproveInfoModel>();
		list.add(approve);
		List<Map<String,Object>> data = getData(list);
		return getInfo(data,false).get(0);
		
	}
	@Override
	public List<PrintInfo> getInfoExcel(List<? extends ActExApproveInfoModel> approveList){
		List<Map<String,Object>> data = getData(approveList);
		return getInfo(data,true);
	}
	
	/**
	 * 获取流程表单数据
	 * @param listInfo
	 * @return
	 */
	private List<Map<String,Object>> getData(List<? extends ActExApproveInfoModel> listInfo){
		List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
		List<FtpModel> ftps = new ArrayList<FtpModel>();
		for(ActExApproveInfoModel info:listInfo){
			String path = info.getPath();
			if(Validata.isNullOrEmpty(path)){
				Map<String,Object> data = queryInfoFromDB(info.getBusinessid(), info.getProcesskey());
				result.add(data);
			}else{
				FtpModel ftp = getFtpModel(path);
				ftps.add(ftp);
			}
		}
		if(ftps.size()>0){
			List<Map<String,Object>> overList = actProgressTableService.queryOverInfoList(ftps);
			result.addAll(overList);
		}

		return result;
	}
	
	/**
	 * 将流程数据封装到PrintInfo
	 * @param dataList
	 * @param excel 值为true,封装成excel需求格式，否则为pdf需求格式
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private List<PrintInfo> getInfo(List<Map<String,Object>> dataList,Boolean excel){
		List<PrintInfo> printList =new ArrayList<PrintInfo>();
		for(Map<String,Object> data: dataList){
			PrintInfo print = new PrintInfo();
			int index = 1;
			String taskId;
			String nodeName;
			String persionName;
			String agree;
			String dealTime;
			String businessId = null;
			String userId = null;
			List<Map<String, Object>> formList = (List<Map<String, Object>>)data.get("data");
			ArrayList<Approval> approvals = new ArrayList<Approval>();
			List<Map<String,Object>> forms = new ArrayList<Map<String,Object>>();
			for(Map<String, Object> form:formList){
				taskId = form.get("taskid")+"";
				nodeName = form.get("processnodename")+"";
				persionName = form.get("username")+"";
				agree = form.get("action")+"";
				dealTime = form.get("dealtime")+"";
				String formIndex="";
				if(Contants.FORM_PROCESS_MAIN_TASKID.equals(taskId) 
						|| Contants.FORM_PROCESS_START.equals(form.get("processnodeid"))){
					businessId = form.get("businessid")+"";
					userId = form.get("userid")+"";
				}
				//表单
				if(Validata.notNullOrEmpty(taskId) && !"转交".equals(agree)){//转交没有提交任何表单					
					if(excel){
						if(Contants.FORM_PROCESS_MAIN_TASKID.equals(taskId)){
							Map<String, Object> excelForm = new HashMap<String,Object>();
							getFormOfExcel(form,excelForm);
							print.setMainForm(excelForm);
						}
					}else{
						formIndex = index+"";
						Map<String, Object> item = new HashMap<String,Object>();
						getForm(form,item);
						item.put("index", formIndex);
						forms.add(item);
					}
				}
				//审批人
				if(!Contants.FORM_PROCESS_MAIN_TASKID.equals(taskId)){
					Approval approval = new Approval(persionName,agree,dealTime,nodeName,formIndex);
					approvals.add(approval);
				}
				index++;
				}	

			//查询发起人信息
			Map<String, String> map = new HashMap<String, String>();
			map.put("userId", userId);
			List<UserModel> users = userServiceImpl.queryUser(map);
			if(users == null || users.isEmpty()){
				continue;
			}
			UserModel startUser = users.get(0);
			OaActExApproveInfoModel process = this.queryProcessInfo(businessId);
			if(process == null){
				continue;
			}
			print.setProcessName(process.getProcessname());
			print.setStartUser(startUser.getUserName());
			print.setStartUserDept(startUser.getDeptName());
			print.setStartTime(process.getStarttime());
			print.setEndTime(process.getEndtime());
			print.setStatusText(process.getStatusText());
			print.setForms(forms);
			print.setApprovalInfo(approvals);
			printList.add(print);
		}		
		return printList;		
	}
	
	private FtpModel getFtpModel(String url){
		FtpModel ftp = null;
		if(Validata.notNullOrEmpty(url)){
			String path= url.substring(url.lastIndexOf("/")+1);
			path = path.substring(0,path.lastIndexOf("_")+1).replace("_", "/");
			path = path.substring(1,path.length());
			String fileName = url.substring(url.lastIndexOf("/")+1);
			fileName = fileName.substring(fileName.lastIndexOf("_")+1);
			ftp = new FtpModel();
			ftp.setFilePath(path);
			ftp.setFileNewName(fileName);
		}
		return ftp;
	}
	/**
	 * 从数据库查询未完结流程表单数据，数据结构与完结流程相同
	 * @param busId
	 * @param processKey
	 * @return
	 * @throws Exception
	 */
	private Map<String,Object> queryInfoFromDB(String businessId,String processKey){
		MyHashMap<String, Object> temp = null;
		MyHashMap<String, String> map = null;
		Entry<String, String> entry = null;
		List<MyHashMap<String, Object>> content = new ArrayList<MyHashMap<String, Object>>();
		List<MyHashMap<String, String>> follows = actExDataFollowMapper.queryActExDataFollow(businessId);
		if(follows!=null){
			String taskId;
			for(int i=0,j=follows.size();i<j;i++){
				map = follows.get(i);
				taskId = map.get("taskid");
				if(Validata.notNullOrEmpty(taskId)){
					if("转交".equals(map.get("action"))){
						temp = new MyHashMap<String, Object>();
					}else{
						temp = actProgressTableService.queryBussInfo(processKey,map.get("processnodeid"),businessId,map.get("taskid"));
					}
				}else{
					temp = new MyHashMap<String, Object>();
				}			
				if(temp!=null){
					Iterator<Entry<String, String>> it = map.entrySet().iterator();
					while (it.hasNext()) {
						entry = it.next();
						temp.put(entry.getKey(), entry.getValue());
					}
					if(Contants.FORM_PROCESS_MAIN_TASKID.equals(taskId)){
						temp.put("businessId", businessId);
					}
					content.add(temp);
				}
			}
		}
		Map<String,Object> rs = new HashMap<String,Object>();
		rs.put("data", content);
		return rs;
	}
	
	@SuppressWarnings("unchecked")
	private void getForm(Map<String, Object> oldForm,Map<String, Object> newForm){
		List<Map<String, Object>> mains = (List<Map<String, Object>>) oldForm.get(Contants.FORM_KEY_MAIN);
		List<Map<String, Object>> subs = (List<Map<String, Object>>) oldForm.get(Contants.FORM_KEY_SUBS);
		List<Map<String, Object>> form = new ArrayList<Map<String, Object>>();
		form.addAll(mains);
		form.addAll(subs);
		newForm.put("data",form);
	}

	@SuppressWarnings("unchecked")
	private void getFormOfExcel(Map<String, Object> oldForm,Map<String, Object> newForm){		
		List<Map<String, Object>> mains = (List<Map<String, Object>>) oldForm.get(Contants.FORM_KEY_MAIN);
		List<Map<String, Object>> subs = (List<Map<String, Object>>) oldForm.get(Contants.FORM_KEY_SUBS);
		
		Map<String,String> mainInfo = new LinkedHashMap<String,String>();
		for(Map<String, Object> main : mains){
			List<Map<String,String>> list = reInstallForm(main);
			if(!list.isEmpty()){
				mainInfo.putAll(list.get(0));
			}
		}
		if(subs != null && !subs.isEmpty()){
			List<Map<String,String>> subInfo = reInstallForm(subs.get(0)); //要求表单配置：发起人表单子表只能配一个，且为多行表单；
			newForm.put("sub",subInfo);
		}
		
		newForm.put("main",mainInfo);

	}
	
	@SuppressWarnings("unchecked")
	private List<Map<String,String>> reInstallForm(Map<String, Object> form){
		List<Map<String,String>> newForm = new ArrayList<Map<String,String>>();
		if(form != null && !form.isEmpty()){
				List<Map<String, Object>> datas = (List<Map<String, Object>>) form.get(Contants.FORM_KEY_DATA);
				List<Map<String, Object>> clos = (List<Map<String, Object>>) form.get(Contants.FORM_KEY_COLS);
			
				Map<String, String> colName = new LinkedHashMap<String, String>();
				for(Map<String, Object> col : clos){
					if(Contants.FORM_SHOWTYPE_HIDDEN.equals((String)col.get("showtype"))){
						continue;
					}else{
						colName.put((String)col.get("colname"), (String)col.get("colnamech"));
					}
				}
				for(int i=0;i<datas.size();i++){
					Map<String, String> data = new LinkedHashMap<String,String>();
					for(Map.Entry<String, String> entry : colName.entrySet()){
						if(datas.get(i) != null && datas.get(i).get(entry.getKey()) != null){						
							data.put(colName.get(entry.getKey()),String.valueOf(datas.get(i).get(entry.getKey())));
						}else{
							data.put(colName.get(entry.getKey()),"");
						}
					}
					newForm.add(data);
				}
		}
		return newForm;
	}
	
}
